package org.dashboard.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import org.dashboard.bean.AdDatasource;
import org.dashboard.bean.AdRole;
import org.dashboard.bean.AdUser;
import org.dashboard.bean.JsonResponse;
import org.dashboard.service.AdDatasourceService;
import org.dashboard.utils.NameCastTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/dataset/source")
public class AdDatasourceController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(AdDatasourceController.class);

    @Reference
    private AdDatasourceService adDatasourceService;


    @RequestMapping(value = "/search", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse search(HttpServletRequest request) {
        String criteria = request.getParameter("criteria");
        Integer pageIndex = Integer.parseInt(request.getParameter("pageIndex"));
        Integer pageSize = Integer.parseInt(request.getParameter("pageSize"));

        PageInfo pageInfo = adDatasourceService.selectAdDatasourcesPaged(criteria, pageIndex, pageSize);

        JsonResponse jsonResponse = new JsonResponse();
        Map<String, Object> map = new HashMap<>();

        map.put("items", NameCastTools.listToListMap(pageInfo.getList()));
        map.put("count", pageInfo.getTotal());

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/all", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse all(HttpServletRequest request) {

        List<AdDatasource> adDatasources = adDatasourceService.selectAdDatasources();
        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(NameCastTools.listToListMap(adDatasources));

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/add", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse add(HttpServletRequest request) {
        String sourceName = request.getParameter("sourceName");
        String sourceIp = request.getParameter("sourceIp");
        String sourcePort = request.getParameter("sourcePort");
        String sourceUser = request.getParameter("sourceUser");
        String sourcePassword = request.getParameter("sourcePassword");
        String sourceDatabase = request.getParameter("sourceDatabase");
        Integer sourceType = Integer.parseInt(request.getParameter("sourceType"));

        AdDatasource adDatasource = new AdDatasource();
        adDatasource.setDatasourceName(sourceName);
        adDatasource.setDatasourceIp(sourceIp);
        adDatasource.setDatasourcePort(sourcePort);
        adDatasource.setDatasourceUser(sourceUser);
        adDatasource.setDatasourcePassword(sourcePassword);
        adDatasource.setDatasourceDatabase(sourceDatabase);
        adDatasource.setDatasourceType(sourceType);

        adDatasource.setDatasourceId(adDatasourceService.insert(adDatasource));
        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(NameCastTools.objectToMap(adDatasource));

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


    @RequestMapping(value = "/delete", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse delete(HttpServletRequest request) {
        String sourceIds = request.getParameter("sourceIds");
        JSONArray jsonArray = (JSONArray) JSON.parse(sourceIds);
        ArrayList<Integer> ids = new ArrayList<>();
        if (jsonArray != null) {
            int len = jsonArray.size();
            for (int i = 0; i < len; i++) {
                ids.add(jsonArray.getInteger(i));
            }
        }
        adDatasourceService.deleteByPrimaryKeys(ids);
        return JsonResponse.success();
    }

    @RequestMapping(value = "/update", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse update(HttpServletRequest request) {
        Integer sourceId = Integer.parseInt(request.getParameter("sourceId"));
        String sourceName = request.getParameter("sourceName");
        String sourceIp = request.getParameter("sourceIp");
        String sourcePort = request.getParameter("sourcePort");
        String sourceUser = request.getParameter("sourceUser");
        String sourcePassword = request.getParameter("sourcePassword");
        String sourceDatabase = request.getParameter("sourceDatabase");
        Integer sourceType = Integer.parseInt(request.getParameter("sourceType"));

        AdDatasource adDatasource = new AdDatasource();
        adDatasource.setDatasourceId(sourceId);
        adDatasource.setDatasourceName(sourceName);
        adDatasource.setDatasourceIp(sourceIp);
        adDatasource.setDatasourcePort(sourcePort);
        adDatasource.setDatasourceUser(sourceUser);
        adDatasource.setDatasourcePassword(sourcePassword);
        adDatasource.setDatasourceDatabase(sourceDatabase);
        adDatasource.setDatasourceType(sourceType);

        adDatasourceService.updateByPrimaryKeySelective(adDatasource);

        adDatasource = adDatasourceService.selectByPrimaryKey(sourceId);
        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(NameCastTools.objectToMap(adDatasource));

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/meta", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse meta(HttpServletRequest request) {
        String sourceIp = request.getParameter("sourceIp");
        String sourcePort = request.getParameter("sourcePort");
        String sourceUser = request.getParameter("sourceUser");
        String sourcePassword = request.getParameter("sourcePassword");
        String sourceDatabase = request.getParameter("sourceDatabase");
        Integer sourceType = Integer.parseInt(request.getParameter("sourceType"));

        AdDatasource adDatasource = new AdDatasource();
        adDatasource.setDatasourceIp(sourceIp);
        adDatasource.setDatasourcePort(sourcePort);
        adDatasource.setDatasourceUser(sourceUser);
        adDatasource.setDatasourcePassword(sourcePassword);
        adDatasource.setDatasourceDatabase(sourceDatabase);
        adDatasource.setDatasourceType(sourceType);

        List<Object[]> tableNames = adDatasourceService.getMetaTableNames(adDatasource);
        List<Object[]> columnNames = adDatasourceService.getMetaColumnNames(adDatasource);

        Map<String, Object> map = new HashMap<>();
        map.put("tables", tableNames);
        map.put("columns", columnNames);

        JsonResponse jsonResponse = new JsonResponse();

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/test", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse test(HttpServletRequest request) {
        String sourceIp = request.getParameter("sourceIp");
        String sourcePort = request.getParameter("sourcePort");
        String sourceUser = request.getParameter("sourceUser");
        String sourcePassword = request.getParameter("sourcePassword");
        String sourceDatabase = request.getParameter("sourceDatabase");
        Integer sourceType = Integer.parseInt(request.getParameter("sourceType"));

        AdDatasource adDatasource = new AdDatasource();
        adDatasource.setDatasourceIp(sourceIp);
        adDatasource.setDatasourcePort(sourcePort);
        adDatasource.setDatasourceUser(sourceUser);
        adDatasource.setDatasourcePassword(sourcePassword);
        adDatasource.setDatasourceDatabase(sourceDatabase);
        adDatasource.setDatasourceType(sourceType);

        return adDatasourceService.datasourceTest(adDatasource) ? JsonResponse.success() : JsonResponse.failed();
    }

    @RequestMapping(value = "/execute", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse execute(HttpServletRequest request) {
        String sqlStr = request.getParameter("sqlStr");
        String sqlParams = request.getParameter("sqlParams");
        String sourceIp = request.getParameter("sourceIp");
        String sourcePort = request.getParameter("sourcePort");
        String sourceUser = request.getParameter("sourceUser");
        String sourcePassword = request.getParameter("sourcePassword");
        String sourceDatabase = request.getParameter("sourceDatabase");
        Integer sourceType = Integer.parseInt(request.getParameter("sourceType"));

        AdDatasource adDatasource = new AdDatasource();
        adDatasource.setDatasourceIp(sourceIp);
        adDatasource.setDatasourcePort(sourcePort);
        adDatasource.setDatasourceUser(sourceUser);
        adDatasource.setDatasourcePassword(sourcePassword);
        adDatasource.setDatasourceDatabase(sourceDatabase);
        adDatasource.setDatasourceType(sourceType);

        JsonResponse jsonResponse = new JsonResponse();

        AdUser user = currentAdUser(request);
        List<AdRole> roles = currentUserAdRoles(request);

        List<Map<String, Object>> tableDataAll = adDatasourceService.getDataMapExecuteSql(sqlStr, sqlParams, adDatasource, user, roles);

        List<Object[]> data = new ArrayList<>();
        List<String> columns = new ArrayList<>();

        for (Map<String, Object> map : tableDataAll) {
            if (columns.size() == 0) {
                columns = new ArrayList<>(map.keySet());
            }
            data.add(map.values().toArray());
        }

        Map<String, Object> map = new HashMap<>();
        map.put("data", data);
        map.put("columns", columns);

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


    @RequestMapping(value = "/invoke", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse invoke(HttpServletRequest request) {
        String urlService = request.getParameter("urlService");
        String urlFunction = request.getParameter("urlFunction");
        String urlParams = request.getParameter("urlParams");


        JsonResponse jsonResponse = new JsonResponse();

        AdUser user = currentAdUser(request);
        List<AdRole> roles = currentUserAdRoles(request);

        List<Map<String, Object>> tableDataAll = adDatasourceService.getDataMapInvokeService(urlService, urlFunction, urlParams, user, roles);

        List<Object[]> data = new ArrayList<>();
        List<String> columns = new ArrayList<>();

        for (Map<String, Object> map : tableDataAll) {
            if (columns.size() == 0) {
                columns = new ArrayList<>(map.keySet());
            }
            data.add(map.values().toArray());
        }

        Map<String, Object> map = new HashMap<>();
        map.put("data", data);
        map.put("columns", columns);

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


}
